home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Scope / Scope Disk #142 (199x)(Scope PD)(US)[WB].zip / Scope Disk #142 (199x)(Scope PD)(US)[WB].adf / LoadImage / Cycling.c < prev    next >
Text File  |  1990-07-30  |  8KB  |  424 lines

  1. /* $Revision Header * Header built automatically - do not edit! *************
  2.  *
  3.  *    (C) Copyright 1990 by MXM
  4.  *
  5.  *    Name .....: Cycling.c
  6.  *    Created ..: Saturday 23-Sep-90 12:30
  7.  *    Revision .: 2
  8.  *
  9.  *    Date            Author          Comment
  10.  *    =========       ========        ====================
  11.  *    11-May-90       Olsen           Rework for Aztec 5.0 release
  12.  *    23-Sep-89       Olsen           Created this file!
  13.  *
  14.  * $Revision Header *********************************************************
  15.  *
  16.  *    This file contains subroutines handling the colour cycling employed
  17.  *    by LoadImage.c
  18.  *
  19.  ***************************************************************************/
  20.  
  21.     /* LoadCycleRange needs these macros. */
  22.  
  23. #define CRNG_NORATE    (36)        /* Don't cycle this range. */
  24. #define CRNG_ACTIVE    (1 << 0)    /* This range is active. */
  25. #define CRNG_REVERSE    (1 << 1)    /* This range is cycling backwards. */
  26.  
  27.     /* The following values are to control the interrupt code. */
  28.  
  29. #define CY_CYCL (0)    /* Keep on cycling. */
  30. #define CY_WAIT    (1)    /* Don't cycle, wait for startup message. */
  31.  
  32.     /* CycleCode needs this data, InitCycleCode prepares it. */
  33.  
  34. static struct ViewPort    *VPort;            /* Where to cycle. */
  35. static struct Interrupt    *VBlank;        /* The Cycling-interrupt. */
  36. static CRange        *Range;            /* The cycling-ranges. */
  37. static LONG         RangeNum;        /* The number of ranges. */
  38. static UWORD         ColMap[32];        /* The colourmap. */
  39. static LONG         ColNum;        /* The number of colours. */
  40. static SHORT         TicksPassed[16];    /* Event counter for ranges. */
  41. static UWORD         TempCol;        /* Temporary colour buffer. */
  42. static UWORD         UndoBuffer[32];    /* Original palette buffer. */
  43. static SHORT         WeAreWaiting;        /* CycleCode is waiting. */
  44. static SHORT         Command;        /* What is the CycleCode up to do? */
  45. static LONG         CodeRun = FALSE;    /* Is the CycleCode already running? */
  46.  
  47.     /* CycleCode() :
  48.      *
  49.      *    CycleCode is the 'C' cycling routine. It runs as an
  50.      *    interrupt server to save task time.
  51.      */
  52.  
  53. static LONG
  54. CycleCode()
  55. {
  56.     SHORT i,j;    /* Loop counter. */
  57.  
  58.     int_start();
  59.  
  60.         /* Are we to wait? */
  61.  
  62.     if(Command == CY_WAIT)
  63.     {
  64.             /* Restore the original palette. */
  65.  
  66.         if(!WeAreWaiting)
  67.             LoadRGB4(VPort,UndoBuffer,ColNum);
  68.  
  69.         WeAreWaiting = TRUE;
  70.  
  71.         int_end();
  72.  
  73.             /* Don't continue to cycle. */
  74.  
  75.         return(0);
  76.     }
  77.  
  78.         /* We aren't waiting any more. */
  79.  
  80.     if(WeAreWaiting)
  81.     {
  82.             /* Re-initialize the palette. */
  83.  
  84.         for(i = 0 ; i < ColNum ; i++)
  85.             ColMap[i] = UndoBuffer[i];
  86.  
  87.             /* Reset event counters. */
  88.  
  89.         for(i = 0 ; i < RangeNum ; i++)
  90.             TicksPassed[i] = 0;
  91.  
  92.         WeAreWaiting = FALSE;
  93.     }
  94.  
  95.         /* Now handle the cycle ranges. */
  96.  
  97.     for(i = 0 ; i < RangeNum ; i++)
  98.     {
  99.             /* Increment event counter. */
  100.  
  101.         TicksPassed[i]++;
  102.  
  103.             /* Is this one up to cycle next? */
  104.  
  105.         if(TicksPassed[i] == Range[i] . rate)
  106.         {
  107.                 /* Reset event counter for this range. */
  108.  
  109.             TicksPassed[i] = 0;
  110.  
  111.                 /* Is this range active? */
  112.  
  113.             if(!(Range[i] . active & CRNG_ACTIVE))
  114.                 continue;
  115.  
  116.                 /* Cycling backwards? */
  117.  
  118.             if(Range[i] . active & CRNG_REVERSE)
  119.             {
  120.                     /* Move the colours. */
  121.  
  122.                 TempCol = ColMap[Range[i] . low];
  123.  
  124.                 for(j = Range[i] . low ; j < Range[i] . high ; j++)
  125.                     ColMap[j] = ColMap[j + 1];
  126.  
  127.                 ColMap[Range[i] . high] = TempCol;
  128.             }
  129.             else
  130.             {
  131.                     /* This one is cycling forwards. */
  132.  
  133.                 TempCol = ColMap[Range[i] . high];
  134.  
  135.                 for(j = Range[i] . high ; j > Range[i] . low ; j--)
  136.                     ColMap[j] = ColMap[j - 1];
  137.  
  138.                 ColMap[Range[i] . low] = TempCol;
  139.             }
  140.  
  141.                 /* Okay, everything has been moved, now
  142.                  * load the new palette.
  143.                  */
  144.  
  145.             LoadRGB4(VPort,ColMap,ColNum);
  146.         }
  147.     }
  148.  
  149.     int_end();
  150.  
  151.     return(0);
  152. }
  153.  
  154.     /* InitCycleCode(ViewPort,ColMap,ColNum,Range,RangeNum) :
  155.      *
  156.      *    Initializes all data and starts up the interrupt
  157.      *    server.
  158.      */
  159.  
  160. LONG
  161. InitCycleCode(struct ViewPort *Cy_ViewPort,UWORD *Cy_ColMap,LONG Cy_ColNum,CRange *Cy_Range,LONG Cy_RangeNum)
  162. {
  163.     SHORT i;
  164.  
  165.         /* Check for valid parameters. */
  166.  
  167.     if(!Cy_ViewPort || !Cy_ColMap || !Cy_ColNum || !Cy_Range || !Cy_RangeNum)
  168.         return(FALSE);
  169.  
  170.         /* See if we can allocate the Interrupt structure. */
  171.  
  172.     if(!(VBlank = (struct Interrupt *)AllocMem(sizeof(struct Interrupt),MEMF_PUBLIC | MEMF_CLEAR)))
  173.         return(FALSE);
  174.  
  175.         /* Copy the data. */
  176.  
  177.     VPort        = Cy_ViewPort;
  178.     ColNum        = Cy_ColNum;
  179.     Range        = Cy_Range;
  180.     RangeNum    = Cy_RangeNum;
  181.  
  182.     for(i = 0 ; i < ColNum ; i++)
  183.         ColMap[i] = Cy_ColMap[i];
  184.  
  185.         /* Clear event counters. */
  186.  
  187.     for(i = 0 ; i < Cy_RangeNum ; i++)
  188.         TicksPassed[i] = 0;
  189.  
  190.         /* Copy the original palette to the undo buffer. */
  191.  
  192.     for(i = 0 ; i < Cy_ColNum ; i++)
  193.         UndoBuffer[i] = Cy_ColMap[i];
  194.  
  195.         /* Let the CycleCode wait. */
  196.  
  197.     Command        = CY_WAIT;
  198.     WeAreWaiting    = TRUE;
  199.  
  200.         /* Ta Da! The CycleCode enters the stage!. */
  201.  
  202.     VBlank -> is_Code        = CycleCode;
  203.     VBlank -> is_Node . ln_Type    = NT_INTERRUPT;
  204.     VBlank -> is_Node . ln_Name    = "Cycling Interrupt";
  205.  
  206.     AddIntServer(INTB_VERTB,VBlank);
  207.  
  208.     CodeRun = TRUE;
  209.  
  210.     return(TRUE);
  211. }
  212.  
  213.     /* ClearCycleCode() :
  214.      *
  215.      *    Forces the CycleCode to hit and quit.
  216.      */
  217.  
  218. VOID
  219. ClearCycleCode()
  220. {
  221.     SHORT i;
  222.  
  223.         /* Is the interrupt already running? */
  224.  
  225.     if(CodeRun && VBlank)
  226.     {
  227.             /* Tell it to wait. */
  228.  
  229.         WeAreWaiting    = TRUE;
  230.         Command        = CY_WAIT;
  231.  
  232.             /* Remove the server code. */
  233.  
  234.         RemIntServer(INTB_VERTB,VBlank);
  235.  
  236.         FreeMem(VBlank,sizeof(struct Interrupt));
  237.  
  238.             /* Rebuild palette. */
  239.  
  240.         for(i = 0 ; i < ColNum ; i++)
  241.             ColMap[i] = UndoBuffer[i];
  242.  
  243.             /* Wait for it to finish. */
  244.  
  245.         WaitTOF();
  246.         WaitTOF();
  247.         WaitTOF();
  248.  
  249.             /* Close the shop. */
  250.  
  251.         CodeRun = FALSE;
  252.     }
  253. }
  254.  
  255.     /* ToggleCycleCode() :
  256.      *
  257.      *    Toggles the activity of the cycling code.
  258.      */
  259.  
  260. VOID
  261. ToggleCycleCode()
  262. {
  263.     static BYTE Mode = FALSE;
  264.  
  265.     Mode ^= TRUE;
  266.  
  267.     if(Mode)
  268.         Command = CY_CYCL;
  269.     else
  270.         Command = CY_WAIT;
  271.  
  272.     WaitTOF();
  273. }
  274.  
  275.     /* IsCycling() :
  276.      *
  277.      *    Returns the present status of the cycling code.
  278.      */
  279.  
  280. LONG
  281. IsCycling()
  282. {
  283.     if(Command == CY_CYCL)
  284.         return(TRUE);
  285.  
  286.     if(Command == CY_WAIT)
  287.         return(FALSE);
  288. }
  289.  
  290.     /* LoadCycleRange(FileName,Range,MaxRange) :
  291.      *
  292.      *    Searches the IFF-ILBM-file for CRNG or CCRT
  293.      *    chunks und initializes the colour-ranges.
  294.      */
  295.  
  296. LONG
  297. LoadCycleRange(char *FileName,CRange *Range,LONG MaxRange)
  298. {
  299.     FILE    *CycFile;
  300.     SHORT     i;
  301.  
  302.         /* GraphiCraft private cycling chunk. */
  303.  
  304.     struct
  305.     {
  306.         WORD direction;        /* Which direction? */
  307.         UBYTE start;        /* First colour. */
  308.         UBYTE end;        /* Last colour. */
  309.         LONG seconds;        /* Wait time. */
  310.         LONG microseconds;    /* Wait time. */
  311.         WORD pad;        /* Expansion/padding byte. */
  312.     } CcrtChunk;
  313.  
  314.         /* Clear all ranges. */
  315.  
  316.     for(i = 0 ; i < MaxRange ; i++)
  317.         Range[i] . active = 0;
  318.  
  319.         /* Open the file and try to locate the CRNG chunk. */
  320.  
  321.     if(!(CycFile = fopen(FileName,"r")))
  322.         return(FALSE);
  323.  
  324.     if(FindChunk("CRNG",CycFile))
  325.     {
  326.             /* Read all ranges. */
  327.  
  328.         for(i = 0 ; i < MaxRange ; i++)
  329.         {
  330.             fread(&Range[i],sizeof(CRange),1,CycFile);
  331.  
  332.                 /* Carefully determine if this chunk is
  333.                  * active.
  334.                  */
  335.  
  336.             if(Range[i] . active == CRNG_NORATE || !Range[i] . rate || Range[i] . low == Range[i] . high)
  337.                 Range[i] . active = 0;
  338.  
  339.                 /* Recalculate speed value. */
  340.  
  341.             if(Range[i] . rate > 0)
  342.                 Range[i] . rate = 16384 / Range[i] . rate;
  343.             else
  344.                 Range[i] . rate = 0;
  345.  
  346.                 /* Finished reading the chunks? */
  347.  
  348.             if(!FindChunk("CRNG",CycFile))
  349.             {
  350.                 i++;
  351.                 break;
  352.             }
  353.         }
  354.     }
  355.     else
  356.     {
  357.             /* Didn't find a CRNG chunk, try to find a
  358.              * CCRT chunk.
  359.              */
  360.  
  361.         fseek(CycFile,0,0);
  362.  
  363.         if(FindChunk("CCRT",CycFile))
  364.         {
  365.             for(i = 0 ; i < MaxRange ; i++)
  366.             {
  367.                 fread(&CcrtChunk,sizeof(CcrtChunk),1,CycFile);
  368.  
  369.                     /* We have located a CCRT chunk, now
  370.                      * make it a CRNG chunk.
  371.                      */
  372.  
  373.                 Range[i] . low    = CcrtChunk . start;
  374.                 Range[i] . high    = CcrtChunk . end;
  375.  
  376.                 if(CcrtChunk . direction != 0)
  377.                     Range[i] . active = CRNG_ACTIVE;
  378.                 else
  379.                     Range[i] . active = 0;
  380.  
  381.                 if(CcrtChunk . direction > 0)
  382.                     Range[i] . active |= CRNG_REVERSE;
  383.  
  384.                     /* Recalculate speed (by
  385.                      * Carolyn Scheppner).
  386.                      */
  387.  
  388.                 Range[i] . rate    = 16384 / (CcrtChunk . seconds * 60 + (CcrtChunk . microseconds + 8334) / 16667);
  389.  
  390.                     /* See if it is active. */
  391.  
  392.                 if(!Range[i] . rate || Range[i] . low == Range[i] . high)
  393.                     Range[i] . active = 0;
  394.  
  395.                     /* Recalculate speed value. */
  396.  
  397.                 if(Range[i] . rate > 0)
  398.                     Range[i] . rate = 16384 / Range[i] . rate;
  399.                 else
  400.                     Range[i] . rate = 0;
  401.  
  402.                     /* See if there is another chunk. */
  403.  
  404.                 if(!FindChunk("CCRT",CycFile))
  405.                 {
  406.                     i++;
  407.                     break;
  408.                 }
  409.             }
  410.         }
  411.         else
  412.         {
  413.                 /* Seems that we failed. */
  414.  
  415.             fclose(CycFile);
  416.             return(FALSE);
  417.         }
  418.     }
  419.  
  420.     fclose(CycFile);
  421.  
  422.     return(i);
  423. }
  424.